package com.zenghm.retrofit2.adapter;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import java.util.concurrent.atomic.AtomicBoolean;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.HttpException;
import retrofit2.Response;

/**
 * <p>2021-04-15: create by zenghm</P>
 *
 * @since 1.1
 */
public final class SafeLiveData<T> extends LiveData<T> {

    // 确保只执行一次
    private final AtomicBoolean started = new AtomicBoolean(false);
    private final Call<T> originalCall;
    private Call<T> currentCall;

    private final MutableLiveData<Throwable> error = new MutableLiveData<>();

    SafeLiveData(Call<T> originalCall) {
        this.originalCall = originalCall;
    }

    @Override
    protected void onActive() {
        super.onActive();
        if (started.get()) {
            return;
        }
        // 同一个Call只能执行一次，所以这边每次都克隆一个新对象执行。
        currentCall = originalCall.clone();
        if (!hasActiveObservers()) {
            return;
        }
        currentCall.enqueue(new Callback<T>() {
            @Override
            public void onResponse(@NonNull Call<T> call, @NonNull Response<T> r) {
                if (hasActiveObservers()) {
                    if (r.isSuccessful()) {
                        postValue(r.body());
                    } else {
                        postError(new HttpException(r));
                    }
                    started.set(true);
                }
            }

            @Override
            public void onFailure(@NonNull Call<T> call, @NonNull Throwable t) {
                if (hasActiveObservers()) {
                    postError(t);
                    started.set(true);
                }
            }
        });
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        currentCall.cancel();
    }

    private void postError(Throwable t) {
        error.postValue(t);
    }

    public LiveData<Throwable> error() {
        return error;
    }
}
